/**
 * de.herberlin.sudoku.FileService
 */
package de.herberlin.sudoku;

import java.awt.Window;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.logging.Logger;

import javax.jnlp.BasicService;
import javax.jnlp.FileContents;
import javax.jnlp.FileOpenService;
import javax.jnlp.PrintService;
import javax.jnlp.ServiceManager;
import javax.jnlp.UnavailableServiceException;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import de.herberlin.sudoku.gui.HelpWindow;

/**
 * @author herberlin
 * @created 12.07.2006
 */
public abstract class FileService {

	private static transient Logger logger=Logger.getLogger(FileService.class.getName());

	public static final String EXTENSION="sudoku";

	private static Class implClass=null;

	public static FileService getInstance() throws InstantiationException, IllegalAccessException {

		if (implClass==null) {
			try {
			Class.forName("javax.jnlp.ServiceManager");
			ServiceManager.lookup("javax.jnlp.FileOpenService");
			implClass=WebstartFs.class;
			} catch (Exception e) {
				logger.info(e+"");
				implClass=ApplicationFs.class;
			}
			logger.info("FileService="+implClass);
		}

		return (FileService)implClass.newInstance();
	}


	public abstract InputStream getInputStream(Window parent) throws Exception;
	public abstract OutputStream getOutputStream(Window parent) throws Exception;

	public abstract void navigate(URL url) throws Exception;
	public abstract void print(Printable printable) throws Exception;

	static class  ApplicationFs extends FileService {

		public InputStream getInputStream(Window parent) throws FileNotFoundException {
			File file = chooseFile(parent,"file.open");
			logger.fine("File=" + file);
			if (file == null)
				return null;

				return new FileInputStream(file);
		}

		public OutputStream getOutputStream(Window parent) throws FileNotFoundException {
			File file = chooseFile(parent,"file.save");
			logger.fine("File=" + file);
			if (file == null)
				return null;

			return 	new FileOutputStream(file);
		}

		private File chooseFile(Window parent,String messageKey) {
			JFileChooser chooser = new JFileChooser();
			chooser.setFileFilter(new FileFilter() {
				public boolean accept(File file) {
					if (file == null) {
						return false;
					} else {
						return file.getAbsolutePath().endsWith(EXTENSION);
					}
				}

				public String getDescription() {
					return EXTENSION;
				}

			});
			int returnVal = chooser.showDialog(parent, Main.getMessage(messageKey));
			if (returnVal == JFileChooser.APPROVE_OPTION) {
				return chooser.getSelectedFile();
			} else {
				return null;
			}
		}

		public void navigate(URL url) throws IOException {
				new HelpWindow("Sudoku",url);
		}

		public void print(Printable printable) throws Exception {

			PrinterJob job=PrinterJob.getPrinterJob();
			job.setPrintable(printable);
			if (job.printDialog()) {
				job.print();
			}
		}
	}

	static class WebstartFs extends FileService {

		public InputStream getInputStream(Window parent) throws Exception {
			FileOpenService service=(FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
			FileContents fileContents=service.openFileDialog(null,new String[]{EXTENSION});
			return fileContents.getInputStream();
		}

		public OutputStream getOutputStream(Window parent) throws Exception {
			FileOpenService service=(FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
			FileContents fileContents=service.openFileDialog(null,new String[]{EXTENSION});
			return fileContents.getOutputStream(true);
		}

		public void navigate(URL url) throws UnavailableServiceException {

			BasicService basicService=(BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
			basicService.showDocument(url);
		}

		public void print(Printable printable) throws Exception {
			PrintService printService=(PrintService)ServiceManager.lookup("javax.jnlp.PrintService");
			printService.print(printable);
		}

	}
}
